the “enabled-extension” setting.
</description>
</key>
+ <key name="allow-extension-installation" type="b">
+ <default>true</default>
+ <summary>Allow extension installation</summary>
+ <description>
+ Allow users to install extensions in their home folder. If disabled,
+ the InstallRemoteExtension D-Bus method will fail, and extensions
+ are only loaded from system directories on startup.
+ It does not affect extensions that are already loaded, so a change
+ only takes full effect on the next login.
+ </description>
+ </key>
<key name="disable-extension-version-validation" type="b">
<default>false</default>
<summary>Disables the validation of extension version compatibility</summary>
DOWNLOAD_FAILED: 1,
EXTRACT_FAILED: 2,
ENABLE_FAILED: 3,
+ NOT_ALLOWED: 4,
};
export const ExtensionErrors =
registerErrorDomain('Extensions', ExtensionError);
* @returns {void}
*/
export async function installExtension(uuid, invocation) {
+ if (!global.settings.get_boolean('allow-extension-installation')) {
+ invocation.return_error_literal(
+ ExtensionErrors, ExtensionError.NOT_ALLOWED,
+ 'Extension installation is not allowed');
+ return;
+ }
+
const params = {
uuid,
shell_version: Config.PACKAGE_VERSION,
get updatesSupported() {
const appSys = Shell.AppSystem.get_default();
- return (appSys.lookup_app('org.gnome.Extensions.desktop') !== null) ||
- (appSys.lookup_app('com.mattjakeman.ExtensionManager.desktop') !== null);
+ const hasUpdatesApp =
+ appSys.lookup_app('org.gnome.Extensions.desktop') !== null ||
+ appSys.lookup_app('com.mattjakeman.ExtensionManager.desktop') !== null;
+ const allowed = global.settings.get_boolean('allow-extension-installation');
+ return allowed && hasUpdatesApp;
}
lookup(uuid) {
let perUserDir = Gio.File.new_for_path(global.userdatadir);
- const extensionFiles = [...FileUtils.collectFromDatadirs('extensions', true)];
+ const includeUserDir = global.settings.get_boolean('allow-extension-installation');
+ const extensionFiles = [...FileUtils.collectFromDatadirs('extensions', includeUserDir)];
const extensionObjects = extensionFiles.map(({dir, info}) => {
let fileType = info.get_file_type();
if (fileType !== Gio.FileType.DIRECTORY)